package com.blog.wu.myblog.shiro;

import com.blog.wu.myblog.entity.Permission;
import com.blog.wu.myblog.entity.Role;
import com.blog.wu.myblog.entity.UserInfo;
import com.blog.wu.myblog.service.PermissionService;
import com.blog.wu.myblog.service.RoleService;
import com.blog.wu.myblog.service.UserInfoService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * @Author wuyanshen
 * @Date 2018-11-02 11:28 AM
 * @Discription 系统安全认证类
 */
@Service
public class MyShiroRealm extends AuthorizingRealm {

    /**
     * @Lazy作用:不加这个注解,在UserInfoService中@Cacheable就不生效
     *
     * @date 2019/1/11 3:41 PM
     * @author wuyanshen
     */
    @Autowired
    @Lazy
    private UserInfoService userInfoService;

    @Autowired
    @Lazy
    private RoleService roleService;

    @Autowired
    @Lazy
    private PermissionService permissionService;

    public MyShiroRealm() {
        setCachingEnabled(true);//禁用缓存
    }


    /**
     * 必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    //组装用户角色和权限给shiro

    /**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        UserInfo userInfo = (UserInfo) principalCollection.getPrimaryPrincipal();
        //查询用户名
//        UserInfo user = new UserInfo();
//        user.setUserAccount(userAccount);
//        UserInfo userInfo = userInfoService.get(user);
//        List<String> roles = roleService.findRoles(userInfo);
//        List<String> permissions = permissionService.findPermissions(userInfo);


        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : userInfo.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            for (Permission permission : role.getPermissions()) {
                //添加权限
                simpleAuthorizationInfo.addStringPermission(permission.getPermissionName());
            }
        }
//        simpleAuthorizationInfo.addRoles(roles);
//        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    //用户认证

    /**
     * 认证回调函数, 登录时调用
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取登录信息
        String userAccount = authenticationToken.getPrincipal().toString();
        //查询用户名
        UserInfo user = new UserInfo();
        user.setUserAccount(userAccount);
        UserInfo userInfo = userInfoService.isLogin(user);
        if (userInfo == null) {
            //返回null会报相应异常
            throw new UnknownAccountException("该用户不存在");
        }

        // 账号锁定
        if (userInfo.getUserMark().equals("0")) {
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }

        //验证AuthenticationToken和AuthorizationInfo信息
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userInfo, userInfo.getUserPassword(), getName());

        return simpleAuthenticationInfo;
    }
}